﻿using System;
using System.Text;
using System.Drawing;
using System.IO.Ports;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
namespace CheckClicker
{
    class CommunicationManager
    {
        public int a = 0;
        public int b = 0;
        public int c = 0;
        public int d = 0;
        public int f = 0;

        private OleDbConnection objConnect;
        private DataTable objDataTable;
        private enum varMode : int { AddMode, EditMode, DeleteMode }
        public int sum;
        public int sum1=0;
        public string x1, x2, x3, x4, x5;
        #region "Tạo Kết nối và hủy kết nối"

        private void subCreateConnect()
        {
            String varChuoiConnect = "Provider = Microsoft.Jet.OLEDB.4.0 ;" +
                        "Data Source =" + Application.StartupPath + @"\Database.mdb;" +
                        "User ID = Admin";
            objConnect = new OleDbConnection(varChuoiConnect);
            objConnect.Open(); //Mở kết nối
        }

        private void subDestroyConnect()
        {
            objConnect.Close(); //Đóng kết nối
            objConnect.Dispose();//Giải phóng tài nguyên
            objConnect = null; //Hủy đối tượng
        }
        #endregion
        #region "Add du lieu vao bang AddID"
        private void subInsertByAdapterCommandBuilder1(string id)
        {
            //Tạo kết nối tới file Access
            subCreateConnect();
            //Nạp dữ liệu vào DataTable
            objDataTable = new DataTable("Abc");
            //Tạo đối tượng Adapter và Fill vào DataTable
            OleDbDataAdapter objAdapter = new OleDbDataAdapter("select * from AddID", objConnect);
            objAdapter.Fill(objDataTable);
            //Tạo command cho Adapter
            new OleDbCommandBuilder(objAdapter);
            //Insert dữ liệu vào DataTable
            DataRow objRow = objDataTable.NewRow();
            objRow["ID"] = id;
            objDataTable.Rows.Add(objRow);
            //Insert dữ liệu vào nguồn
            objAdapter.Update(objDataTable);
            //Hủy đối tượng
            subDestroyConnect();
        }
        #endregion

        #region "Add du lieu vao bang Report"
        private void subInsertByAdapterCommandBuilder2(string _id, string _ans)
        {
            //Tạo kết nối tới file Access
            subCreateConnect();
            //Tạo đối tượng Command
            OleDbCommand objCommand = new OleDbCommand();
            objCommand.Connection = objConnect;
            objCommand.CommandType = CommandType.Text;
            objCommand.CommandText = "Insert into Report values(" +
                                    "'" + _id + "'" + "," +
                                    "'" + _ans + "'" + ")";
            objCommand.ExecuteNonQuery();
            //Hủy đối tượng
            objCommand.Dispose();
            objCommand = null;
            subDestroyConnect();
        }
        #endregion
        
        #region Manager Enums
        /// <summary>
        /// enumeration to hold our transmission types
        /// </summary>
        public enum TransmissionType { Text, Hex }

        /// <summary>
        /// enumeration to hold our message types
        /// </summary>
        public enum MessageType { Incoming, Outgoing, Normal, Warning, Error };
        #endregion

        #region Manager Variables
        //property variables
        private string _stop = string.Empty;
        private string _baudRate = string.Empty;
        private string _parity = string.Empty;
        private string _stopBits = string.Empty;
        private string _dataBits = string.Empty;
        private string _portName = string.Empty;
        private TransmissionType _transType;
        //global manager variables
        private Color[] MessageColor = { Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red };
        private SerialPort comPort = new SerialPort();
        #endregion

        #region Manager Properties
        /// <summary>
        /// Property to hold the BaudRate
        /// of our manager class
        /// </summary>
        /// 

        public string Stop
        {
            get { return _stop; }
            set { _stop = value; }
        }

        
        public string BaudRate
        {
            get { return _baudRate; }
            set { _baudRate = value; }
        }

        /// <summary>
        /// property to hold the Parity
        /// of our manager class
        /// </summary>
        public string Parity
        {
            get { return _parity; }
            set { _parity = value; }
        }

        /// <summary>
        /// property to hold the StopBits
        /// of our manager class
        /// </summary>
        public string StopBits
        {
            get { return _stopBits; }
            set { _stopBits = value; }
        }

        /// <summary>
        /// property to hold the DataBits
        /// of our manager class
        /// </summary>
        public string DataBits
        {
            get { return _dataBits; }
            set { _dataBits = value; }
        }

        /// <summary>
        /// property to hold the PortName
        /// of our manager class
        /// </summary>
        public string PortName
        {
            get { return _portName; }
            set { _portName = value; }
        }

        /// <summary>
        /// property to hold our TransmissionType
        /// of our manager class
        /// </summary>
        public TransmissionType CurrentTransmissionType
        {
            get { return _transType; }
            set { _transType = value; }
        }

        /// <summary>
        /// property to hold our display window
        /// value
        /// </summary>
        #endregion

        #region Manager Constructors
        /// <summary>
        /// Constructor to set the properties of our Manager Class
        /// </summary>
        /// <param name="baud">Desired BaudRate</param>
        /// <param name="par">Desired Parity</param>
        /// <param name="sBits">Desired StopBits</param>
        /// <param name="dBits">Desired DataBits</param>
        /// <param name="name">Desired PortName</param>
        /*public CommunicationManager(string baud, string par, string sBits, string dBits, string name, RichTextBox rtb)
        {
            _baudRate = baud;
            _parity = par;
            _stopBits = sBits;
            _dataBits = dBits;
            _portName = name;
            //now add an event handler
            comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
        }
        */
        /// <summary>
        /// Comstructor to set the properties of our
        /// serial port communicator to nothing
        /// </summary>
        public CommunicationManager()
        {
            subCreateConnect();
            //Truy vấn dữ liệu
            String varSelect = "Select * from Comport";//Lệnh SQL
            OleDbCommand objCommand = new OleDbCommand(varSelect, objConnect);
            //Tạo DataReader nhận dữ liệu trả về
            OleDbDataReader objReader = objCommand.ExecuteReader();
            objDataTable = new DataTable("abc");
            objDataTable.Load(objReader);
            DataRow objRow = objDataTable.Rows[0];
           // _portName = objRow["Name"].ToString();
            int k = Convert.ToInt32(objRow["STT"].ToString());
            _baudRate = string.Empty;
            _parity = string.Empty;
            _stopBits = string.Empty;
            _dataBits = string.Empty;
            _portName = objRow["Name"].ToString();
            //add event handler
            comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
        }
        #endregion

        #region "Close Comport"
        public bool closePort()
        { 
            //now close the port
            comPort.Close();
            return false;
        }
        #endregion

        #region WriteData
        public void WriteData(string msg)
        {
            switch (CurrentTransmissionType)
            {
                case TransmissionType.Text:
                    //first make sure the port is open
                    //if its not open then open it
                    if (!(comPort.IsOpen == true)) comPort.Open();
                    //send the message to the port
                    comPort.Write(msg);
            
                    break;
                case TransmissionType.Hex:
                    try
                    {
                        //convert the message to byte array
                        byte[] newMsg = HexToByte(msg);
                        //send the message to the port
                        comPort.Write(newMsg, 0, newMsg.Length);
                        //convert back to hex and display
                       
                    }
                    catch (FormatException ex)
                    {
                        //display error message
                        Console.WriteLine(ex.Message);
                    }
                    finally
                    {
                        Console.WriteLine("...");
                    }
                    break;
                default:
                    //first make sure the port is open
                    //if its not open then open it
                    if (!(comPort.IsOpen == true)) comPort.Open();
                    //send the message to the port
                    comPort.Write(msg);
                    //display the message
                   
                    break;
            }
        }
        #endregion

        #region HexToByte
        /// <summary>
        /// method to convert hex string into a byte array
        /// </summary>
        /// <param name="msg">string to convert</param>
        /// <returns>a byte array</returns>
        private byte[] HexToByte(string msg)
        {
            //remove any spaces from the string
            msg = msg.Replace(" ", "");
            //create a byte array the length of the
            //divided by 2 (Hex is 2 characters in length)
            byte[] comBuffer = new byte[msg.Length / 2];
            //loop through the length of the provided string
            for (int i = 0; i < msg.Length; i += 2)
                //convert each set of 2 characters to a byte
                //and add to the array
                comBuffer[i / 2] = (byte)Convert.ToByte(msg.Substring(i, 2), 16);
            //return the array
            return comBuffer;
        }
        #endregion

        #region ByteToHex
        /// <summary>
        /// method to convert a byte array into a hex string
        /// </summary>
        /// <param name="comByte">byte array to convert</param>
        /// <returns>a hex string</returns>
        private string ByteToHex(byte[] comByte)
        {
            //create a new StringBuilder object
            StringBuilder builder = new StringBuilder(comByte.Length * 3);
            //loop through each byte in the array
            foreach (byte data in comByte)
                //convert the byte to a string and add to the stringbuilder
                builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));
            //return the converted value
            return builder.ToString().ToUpper();
        }
        #endregion


        #region OpenPort
        public bool OpenPort()
        {
            try
            {
                //first check if the port is already open
                //if its open then close it
                if (comPort.IsOpen == true) comPort.Close();

                //set the properties of our SerialPort Object
                comPort.BaudRate = int.Parse(_baudRate);    //BaudRate
                comPort.DataBits = int.Parse(_dataBits);    //DataBits
                comPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _stopBits);    //StopBits
                comPort.Parity = (Parity)Enum.Parse(typeof(Parity), _parity);    //Parity
                comPort.PortName = _portName;   //PortName
                //now open the port
                comPort.Open();
             
                //return true
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error");
                return false;
            }
        }
        #endregion

        #region OpenPort1
        public bool OpenPort1(string _baud, string _data, string _stop, string _parity, string _portName, string msg)
        {
            try
            {
                //first check if the port is already open
                //if its open then close it
                if (comPort.IsOpen == true) comPort.Close();

                //set the properties of our SerialPort Object
                comPort.BaudRate = int.Parse(_baud);    //BaudRate
                comPort.DataBits = int.Parse(_data);    //DataBits
                comPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _stop);    //StopBits
                comPort.Parity = (Parity)Enum.Parse(typeof(Parity), _parity);    //Parity
                comPort.PortName = _portName;   //PortName
                //now open the port
                comPort.Open();
                comPort.Write(msg);
                //return true
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error");
                return false;
            }
        }
        #endregion

        #region SetParityValues
        public void SetParityValues(object obj)
        {
            foreach (string str in Enum.GetNames(typeof(Parity)))
            {
                ((ComboBox)obj).Items.Add(str);
            }
        }
        #endregion

        #region SetStopBitValues
        public void SetStopBitValues(object obj)
        {
            foreach (string str in Enum.GetNames(typeof(StopBits)))
            {
                ((ComboBox)obj).Items.Add(str);
            }
        }
        #endregion
        #region "Add du lieu vao bang Chart"
        private void subInsertByAdapterCommandBuilder(string ans, decimal cent)
        {
            //Tạo kết nối tới file Access
            subCreateConnect();
            //Nạp dữ liệu vào DataTable
            objDataTable = new DataTable("Abc");
            //Tạo đối tượng Adapter và Fill vào DataTable
            OleDbDataAdapter objAdapter = new OleDbDataAdapter("select * from Chart", objConnect);
            objAdapter.Fill(objDataTable);
            //Tạo command cho Adapter
            new OleDbCommandBuilder(objAdapter);
            //Insert dữ liệu vào DataTable
            DataRow objRow = objDataTable.NewRow();
            objRow["Ans"] = ans;
            objRow["Cent"] = Convert.ToInt32(cent);
            objDataTable.Rows.Add(objRow);
            //Insert dữ liệu vào nguồn
            objAdapter.Update(objDataTable);
            //Hủy đối tượng
            subDestroyConnect();
        }
        #endregion

        #region SetPortNameValues
        public void SetPortNameValues(object obj)
        {

            foreach (string str in SerialPort.GetPortNames())
            {
                ((ComboBox)obj).Items.Add(str);
            }
        }
        #endregion


        #region comPort_DataReceived
        /// <summary>
        /// method that will be called when theres data waiting in the buffer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            
            //determine the mode the user selected (binary/string)
            switch (CurrentTransmissionType)
            {
                //user chose string
                case TransmissionType.Text:
                    string msg = "";
                    string key1 = "";
                    string id1 = "";
                    string ans = "";
                    string time = "";
                    //read data waiting in the buffer
                    msg = comPort.ReadExisting();
                    MessageBox.Show(msg);
                    char[] ms = msg.ToCharArray();
                    int len = msg.Length;
                    for (int i = 0; i < len; i++)
                    {
                        if ((i >= 0) && (i < 3)) { key1 += ms[i]; }
                    }
                    //MessageBox.Show(key1);
                    if (key1.Equals("RESR"))
                    {
                        for (int j = 0; j < len; j++)
                        {
                            if ((j >= 4) && (j < len)) { id1 += ms[j]; }
                        }
                        subInsertByAdapterCommandBuilder1(id1);
                        //MessageBox.Show(id1);
                    }
                    else if(key1.Equals("NSR"))
                    {
                        for (int k = 0; k < len; k++)
                        {
                            if ((k >= 3) && (k < 8)) { id1 += ms[k]; }
                            if (k == 8) { ans += ms[k]; }
                           // if ((k > 9) && (k < len)) { time += ms[k]; }
                        }

                        if (ans.Equals("A"))
                        {
                            ++a;
                        }
                        else if (ans.Equals("B"))
                        {
                            ++b;
                        }
                        else if (ans.Equals("C"))
                        {
                            ++c;
                        }
                        else if (ans.Equals("D"))
                        {
                            ++d;
                        }
                        else
                        {
                            ++f;
                        }

                        sum1 = a + b + c + d + f;
                        subInsertByAdapterCommandBuilder2(id1, ans);
                        //MessageBox.Show(ans);

                    }
    
                    break;
                //user chose binary
                case TransmissionType.Hex:
                    string key2 = "";
                    string id2 = "";
                    string ans1 = "";
                    string time1 = "";
                    //retrieve number of bytes in the buffer
                    int bytes = comPort.BytesToRead;
                    //create a byte array to hold the awaiting data
                    byte[] comBuffer = new byte[bytes];
                    //read the data and store it
                    comPort.Read(comBuffer, 0, bytes);
                    //display the data to the user
                    string value = ASCIIEncoding.ASCII.GetString(comBuffer);
                    char[] ms1 = value.ToCharArray();
                    int len1 = value.Length;
                    for (int i = 0; i < len1; i++)
                    {
                        if ((i > 0) && (i < 4)) { key2 += ms1[i]; }
                    }
                    if (key2.Equals("RESR"))
                    {
                        for (int j = 0; j < len1; j++)
                        {
                            if ((j >= 4) && (j < len1)) { id2 += ms1[j]; }
                        }
                        subInsertByAdapterCommandBuilder1(id2);
                        MessageBox.Show(id2);
                    }
                    else
                    {
                        for (int k = 0; k < len1; k++)
                        {
                            if ((k >= 4) && (k < 9)) { id2 += ms1[k]; }
                            if (k == 9) { ans1 += ms1[k]; }
                          
                        }
                        subInsertByAdapterCommandBuilder2(id2, ans1);
                        //MessageBox.Show(ans1);
                    }
                    break;
                default:
                    //read data waiting in the buffer
                    string key3 = "";
                    string id3 = "";
                    string ans2 = "";
                    string time2 = "";
                    string str = comPort.ReadExisting();
                    char[] ms2 = str.ToCharArray();
                    int len2 = str.Length;
                    for (int i = 0; i < len2; i++)
                    {
                        if ((i > 0) && (i < 4)) { key3 += ms2[i]; }
                    }
                    if (key3.Equals("RESR"))
                    {
                        for (int j = 0; j < len2; j++)
                        {
                            if ((j >= 4) && (j < len2)) { id3 += ms2[j]; }
                        }
                        subInsertByAdapterCommandBuilder1(id3);
                        //MessageBox.Show(id3);
                    }
                    else
                    {
                        for (int k = 0; k < len2; k++)
                        {
                            if ((k >= 4) && (k < 9)) { id3 += ms2[k]; }
                            if (k == 9) { ans2 += ms2[k]; }
                            if ((k > 9) && (k < len2)) { time2 += ms2[k]; }
                        }
                        subInsertByAdapterCommandBuilder2(id3, ans2);
                        //MessageBox.Show(ans2);
                    }
                    break;
            }
        }
        #endregion

        public void Reset()
        {
            sum1 = 0;
            a = 0; b = 0; c = 0; d = 0; f = 0;
        }

        public void Result()
        {
            if (_stop.Equals("STOP"))
            {
               
                sum = a + b + c + d + f;
                if (sum != 0)
                {
                    decimal a1 = Math.Round((Decimal)((a * 100) / sum), 0);
                    decimal b1 = Math.Round((Decimal)((b * 100) / sum), 0);
                    decimal c1 = Math.Round((Decimal)((c * 100) / sum), 0);
                    decimal d1 = Math.Round((Decimal)((d * 100) / sum), 0);
                    decimal f1 = Math.Round((Decimal)((f * 100) / sum), 0);
                    subInsertByAdapterCommandBuilder("A", a1);
                    subInsertByAdapterCommandBuilder("B", b1);
                    subInsertByAdapterCommandBuilder("C", c1);
                    subInsertByAdapterCommandBuilder("D", d1);
                    subInsertByAdapterCommandBuilder("E", f1);
                    
                }
                else
                {
                    if (MessageBox.Show("Noone answer!", "Continue?", MessageBoxButtons.OK, MessageBoxIcon.Information) == DialogResult.OK)
                    {
                        // user clicked yes

                    }
                    
                }
            }
        }

        public void NoAnswer()
        {
            x1 = Convert.ToString(a);
            x2 = Convert.ToString(b);
            x3 = Convert.ToString(c);
            x4 = Convert.ToString(d);
            x5 = Convert.ToString(f);
            frmDisplay frm = new frmDisplay(x1, x2, x3, x4, x5);
            frm.ShowDialog();
        }
    }
}